package jmars.mobile.worker;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import jmars.mobile.common.Investigator;
import jmars.mobile.datainvestigation.Summary;

/**
 * rows: groupColumns
 * cols: targetColumns
 * @author Jan
 *
 */
public class AdjacentMatrix implements Investigator {

	@Override
	public Long compute(File[] files, FileWriter writer) throws IOException {
		Long total = 0L;
		Long line=0L;
		FileInputStream fis;
		BufferedReader reader;
		String row;
		String[] cols;
		Map<String,Integer> columnDef=new HashMap<String,Integer>(); //targetColumns
		Map<String,Integer> rowDef=new HashMap<String,Integer>();    //groupColumns
		Integer colSeed=0,rowSeed=0;
		Integer cc,cr;
		Map<Integer,Map<Integer,Integer>> am=new HashMap<Integer,Map<Integer,Integer>>();
		DecimalFormat df = new DecimalFormat();
		df.applyPattern("0,000");
		String tempColKey,tempRowKey;
		for(File inputFile:files){
			fis = new FileInputStream(inputFile);
			reader = new BufferedReader(new InputStreamReader(fis));
			line=0L;
			while((row=reader.readLine())!=null){
				line++;
				cols=row.split(Summary.columnSeperator);
				if(Summary.filterRow(cols,true,true)) continue;
				try{
					for(Integer tidx:Summary.targetColumnIdx){
						tempRowKey=tidx+"#"+cols[tidx];
						if(!rowDef.containsKey(tempRowKey)){
							rowSeed++;
							rowDef.put(tempRowKey, rowSeed);
							am.put(rowSeed, new HashMap<Integer,Integer>());
							cr=rowSeed;
						}else
							cr=rowDef.get(tempRowKey);
						for(Integer gidx:Summary.groupColumnIdx){
							tempColKey=gidx+"#"+cols[gidx];
							if(!columnDef.containsKey(tempColKey)){
								colSeed++;
								columnDef.put(tempColKey, colSeed);
								cc=colSeed;
							}else
								cc=columnDef.get(tempColKey);
							if(am.get(cr).containsKey(cc)){
								am.get(cr).put(cc, am.get(cr).get(cc)+1);
							}else
								am.get(cr).put(cc, 1);
						}
					}
					total++;
				}catch(Exception ex){
					System.out.println("Exception "+ex.getMessage()+" at line "+line+" of "+inputFile.getName());
					System.out.println(row);
					if(!Summary.errorResume){
						ex.printStackTrace();
						System.exit(0);
					}
				}
			}
			reader.close();
			fis.close();
			System.out.println(inputFile.getName()+" finished at "+total);
		}

		ArrayList<Entry<String,Integer>> rl = new ArrayList<Entry<String,Integer>>(rowDef.entrySet());    
          
        Collections.sort(rl, new Comparator<Map.Entry<String, Integer>>() {    
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {    
                return (int) (o1.getValue() - o2.getValue());    
            }    
        });

		ArrayList<Entry<String,Integer>> cl = new ArrayList<Entry<String,Integer>>(columnDef.entrySet());    
          
        Collections.sort(cl, new Comparator<Map.Entry<String, Integer>>() {    
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {    
                return (int) (o1.getValue() - o2.getValue());    
            }    
        });
		writer.write("%total:"+df.format(total)+"\r\n");
		writer.write("%rows:"+df.format(rowSeed)+"\r\n");
		writer.write("%columns:"+df.format(colSeed)+"\r\n");
		writer.write("%*****************row definitions******************\r\n");
		for(Entry<String,Integer> e : rl) {
			writer.write("%"+e.getKey()+","+e.getValue()+"\r\n");
		}
		writer.write("%*****************column definitions******************\r\n");
		for(Entry<String,Integer> e : cl) {
			writer.write("%"+e.getKey()+","+e.getValue()+"\r\n");
		}
		writer.write("%*****************details******************\r\n");
		for(int m=1;m<=rowSeed;m++) {
			for(int n=1;n<=colSeed;n++) {
				if(!am.get(m).containsKey(n))writer.write("0");
				else writer.write(am.get(m).get(n).toString());
				if(n!=colSeed)writer.write(",");
			}
			writer.write("\r\n");
		}
		return total;
	}

}